package com.edu.zhku.wms.service;

import cn.hutool.core.util.StrUtil;
import com.edu.zhku.wms.dto.ModifyPasswordRequest;
import com.edu.zhku.wms.dto.UserQueryDto;
import com.edu.zhku.wms.exception.BaseException;
import com.edu.zhku.wms.mapper.EmployeeMapper;
import com.edu.zhku.wms.mapper.UserMapper;
import com.edu.zhku.wms.pojo.EmployeeExample;
import com.edu.zhku.wms.pojo.User;
import com.edu.zhku.wms.pojo.UserExample;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Feng
 * @since 2021/10/27 22:05
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserMapper userMapper;
    @Autowired
    EmployeeMapper employeeMapper;
    @Autowired
    UserPrincipalService userPrincipalService;
    @Autowired
    PasswordEncoder encoder;

    @Override
    public User selectByPrimaryKey(Integer id) {
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    public PageInfo<User> list(UserQueryDto userQueryDto, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        UserExample userExample = new UserExample();
        if (userQueryDto != null) {
            String keyword = userQueryDto.getKeyword();
            String role = userQueryDto.getRole();
            Boolean isLocked = userQueryDto.getIsLocked();
            Boolean isEnable = userQueryDto.getIsEnable();

            UserExample.Criteria criteria = userExample.createCriteria();
            if (StrUtil.isNotBlank(keyword)) {
                criteria.andUsernameLike("%" + keyword + "%");
            }
            if (StrUtil.isNotBlank(role)) {
                criteria.andRoleEqualTo(role);
            }
            if (isLocked != null) {
                criteria.andIsLockedEqualTo(isLocked);
            }
            if (isEnable != null) {
                criteria.andIsEnableEqualTo(isEnable);
            }
        }
        return new PageInfo<>(userMapper.selectByExample(userExample));
    }

    @Override
    public int addUser(User user) {
        if (user.getUsername() != null) {
            if (userMapper.selectByUsername(user.getUsername()) != null) {
                throw new BaseException("用户名不可重复");
            }
            user.setId(null);
            user.setPassword(encoder.encode(StrUtil.isBlank(user.getPassword()) ? "123456" : user.getPassword()));
            return userMapper.insert(user);
        }
        return 0;
    }

    @Override
    public int deleteUserByPrimaryKey(HttpServletRequest request, Integer id) {
        // 管理员不能删除自己
        if (userPrincipalService.getLoggedInfo(request).getUserId().equals(id)) {
            return 0;
        }
        return userMapper.deleteByPrimaryKey(id);
    }


    @Override
    public int updateUser(HttpServletRequest request, User user) {
        User userInDB = userMapper.selectByPrimaryKey(user.getId());

        if (!StrUtil.equals(userInDB.getUsername(), user.getUsername()) &&  userMapper.selectByUsername(user.getUsername()) != null) {
            throw new BaseException("用户名不可重复");
        }

        // 管理员不能修改自己的启用和锁定状态
        if (userPrincipalService.getLoggedInfo(request).getUserId().equals(user.getId())) {
            user.setIsEnable(userInDB.getIsEnable());
            user.setIsLocked(userInDB.getIsLocked());
        }

        // 只能用户自行修改密码
        user.setPassword(userInDB.getPassword());
        return userMapper.updateByPrimaryKey(user);
    }

    @Override
    public int modifyPassword(ModifyPasswordRequest modifyPasswordRequest) {
        User user = userMapper.selectByUsername(modifyPasswordRequest.getUsername());
        if (user != null && encoder.matches(modifyPasswordRequest.getOldPassword(), user.getPassword())) {
            user.setPassword(encoder.encode(modifyPasswordRequest.getNewPassword()));
            return userMapper.updateByPrimaryKey(user);
        }
        return 0;
    }

    /**
     * 判断指定ID的用户可否被员工绑定
     * @param id 用户ID
     * @return 可否被绑定
     */
    @Override
    public boolean canBeBound(Integer id) {
        User user = userMapper.selectByPrimaryKey(id);
        if (user == null || StrUtil.equals("管理员", user.getRole())) {
            // 想绑定的用户不存在 或 角色为管理员
            return false;
        }
        EmployeeExample employeeExample = new EmployeeExample();
        employeeExample.createCriteria().andUserIdEqualTo(id);
        if (employeeMapper.countByExample(employeeExample) > 0) {
            // 想绑定的用户已被绑定
            return false;
        }
        return true;
    }
}
